<script setup lang="ts">
import { provide, ref, computed, inject, reactive } from 'vue'
import {
  NIcon,
  NSpin,
  NNotificationProvider,
  useNotification,
  NModal,
  NCard,
  NButton,
  NFormItem,
  FormItemRule,
  NInput,
  NForm
} from 'naive-ui'
import { useRouter } from 'vue-router'
import {
  Dismiss16Filled as Close
} from '@vicons/fluent'
import UserService from '@/services/user.service'

const router = useRouter()
const setSpin = inject('setSpin') as (enable: boolean, msg?: string) => number
const userService = new UserService()
const notification = useNotification()
const showSpin = ref(false)
const spinMessage = ref('')
const showChangePwdModal = ref(false)
const showCenterModal = computed(() => userService.showUserCenter.value)
const formInline = reactive({
  oldPassword: '',
  newPassword: '',
  newPasswordCheck: ''
})

const oPasswordAble = ref(false)
const nPasswordAble = ref(false)
const newPasswordCheck = ref(false)

interface UserInfo {
  describe: string;
  id: string;
  role: string;
  roleName: string;
  username: string;
}

let userCenterData: UserInfo = userService.user

const rules = {
  oldPassword: {
    required: true,
    validator (rule: FormItemRule, value: string) {
      if (!value) {
        oPasswordAble.value = false
        return new Error('旧密码不能为空')
      }
      oPasswordAble.value = true
      return true
    },
    trigger: ['input', 'blur']
  },
  newPassword: {
    required: true,
    validator (rule: FormItemRule, value: string) {
      if (!value) {
        nPasswordAble.value = false
        return new Error('密码不能为空')
      } else if (!/(?!.*\s)(?!^[\u4e00-\u9fa5]+$)(?!^[0-9]+$)(?!^[A-z]+$)(?!^[^A-z0-9]+$)^.{8,16}$/.test(value)) {
        nPasswordAble.value = true
        return new Error(' 8~16位的字母数字特殊符号组合，必须同时包含两种')
      }
      nPasswordAble.value = true
      return true
    },
    trigger: ['input', 'blur']
  },
  newPasswordCheck: {
    required: true,
    validator (rule: FormItemRule, value: string) {
      if (!value) {
        newPasswordCheck.value = false
        return new Error('密码不能为空')
      } else if (value !== formInline.newPassword
      ) {
        newPasswordCheck.value = false
        return new Error('新旧密码不一致')
      }
      newPasswordCheck.value = true
      return true
    },
    trigger: ['input', 'blur']
  }
}

/** 关闭个人中心蒙层 */
function closeCenter () {
  showChangePwdModal.value = false
  userService.showUserCenter.value = false
}
/** 关闭修改密码蒙层 */
function closeChangePwd () {
  formInline.newPassword = ''
  formInline.oldPassword = ''
  formInline.newPasswordCheck = ''
  showChangePwdModal.value = false
  userService.showUserCenter.value = true
}

/** 点击修改密码按钮 */
function changPwd () {
  showChangePwdModal.value = true
}

/** 点击退出登录按钮 */
function logOut () {
  userService.logOut().then((res?) => {
    if (res.success) {
      localStorage.removeItem('username')
      router.replace('/login')
    } else {
      setSpin(true, res.message)
      setTimeout(() => setSpin(false, res.message), 1000)
    }
  })
  userService.showUserCenter.value = false
}

/** 点击修改密码页面右上角x */
function nochange () {
  formInline.newPassword = ''
  formInline.oldPassword = ''
  formInline.newPasswordCheck = ''
  showChangePwdModal.value = false
  userService.showUserCenter.value = true
}

/** 确认修改密码 */
async function makeChange () {
  if (!oPasswordAble.value ||
    !nPasswordAble.value ||
    !newPasswordCheck.value) {
    return
  }
  userService.signPassword(formInline.oldPassword).then((resultOldPwd) => {
    userService.signPassword(formInline.newPassword).then(async (resultNewPwd) => {
      const params = {
        username: userService.username,
        oldPwd: resultOldPwd,
        newPwd: resultNewPwd
      }
      let res = await userService.changePwd(params)
      if (!res.success) {
        notification.warning({
          duration: 2000,
          content: res.message
        })
        return
      }
      notification.success({
        duration: 2000,
        content: '修改密码成功'
      })
      /** 修改密码成功后清除数据 关闭蒙层 */
      formInline.newPassword = ''
      formInline.oldPassword = ''
      formInline.newPasswordCheck = ''
      showChangePwdModal.value = false
      userService.showUserCenter.value = false
    })
  })
}

provide('setSpin', (enable: boolean, message?: string) => {
  spinMessage.value = message || ''
  showSpin.value = enable
})
/** 错误警告窗实例 */
let errorNotification: { destroy: () => void }

defineExpose({
  errorHandler (err: Any, _vm?: Any) {
    showSpin.value = false
    errorNotification?.destroy()
    errorNotification = notification.error({
      duration: 3500,
      title: '系统错误',
      content: err.message || err.toString?.() || err
    })
    console.error(err)
  }
})
</script>

<template>
  <n-notification-provider placement="top-right">
    <n-spin :show="showSpin">
      <n-modal v-model:show="showCenterModal" :mask-closable="false">
        <n-card class="userCenter" style="width: 358px ;border-radius: 10px;
    background: #18171D;border: 1px solid #5A5A62;" title="用户中心" :bordered="false" size="huge" role="dialog"
          aria-modal="true">
          <template #header-extra>
            <n-icon>
              <Close @click="closeCenter" />
            </n-icon>
          </template>
          <div class="id">ID : {{userCenterData.id}}</div>
          <div class="userName">用户名 : {{userCenterData.username}}</div>
          <div class="role">账号角色 : {{userCenterData.roleName}}</div>
          <div class="descrip">账号描述 : {{userCenterData.describe}}</div>
          <template #footer>
            <n-button class="changPwd" @click="changPwd" color="rgba(190, 164, 255, 0.4)" round style="color: #fff;
    border: 1px solid #8F83CB;font-size:12px;height: 32px;">修改密码</n-button>
            <n-button class="logOut" @click="logOut" color="rgba(220, 80, 80, 0.4)" round>退出登录</n-button>
          </template>
        </n-card>
      </n-modal>
      <n-modal v-model:show="showChangePwdModal" :mask-closable="false">
        <n-card class="changePwd"
          style="width: 358px ;border-radius: 10px;background: #18171D;border: 1px solid #5A5A62;" title="修改密码"
          :bordered="false" size="huge" role="dialog" aria-modal="true">
          <template #header-extra>
            <n-icon>
              <Close @click="closeChangePwd" />
            </n-icon>
          </template>
          <n-form :rules="rules" :model="formInline" :show-require-mark="false">
            <n-form-item label-width="66" label-placement="left" label-align="right" label="旧密码" path="oldPassword">
              <n-input type="password" v-model:value="formInline.oldPassword" placeholder="请输入旧密码" />
            </n-form-item>
            <n-form-item label-align="right" label-width="66" label-placement="left" label="新密码" path="newPassword">
              <n-input type="password" v-model:value="formInline.newPassword" placeholder="请输入新密码" />
            </n-form-item>
            <n-form-item label-width="66" label-align="right" label-placement="left" label="确认密码"
              path="newPasswordCheck">
              <n-input type="password" v-model:value="formInline.newPasswordCheck" placeholder="确认新密码" />
            </n-form-item>
          </n-form>
          <template #footer>
            <n-button class="nochange" @click="nochange" color="rgba(190, 164, 255, 0.4)" round
              style="margin:0 27px;color: #fff;border: 1px solid #8F83CB;font-size:12px;height: 32px;">取消
            </n-button>
            <n-button class="makeChange" :disabled="(!oPasswordAble ||!nPasswordAble ||!newPasswordCheck)"
              @click="makeChange" color="rgba(220, 80, 80, 0.4)" round>确认</n-button>
          </template>
        </n-card>
      </n-modal>
    </n-spin>
  </n-notification-provider>
</template>

<style lang="less">
html,
body {
  width: 100%;
  height: 100%;
  margin: 0;
  overflow: hidden;
  user-select: none;
  font-size: 16px;
}

#app {
  width: 100%;
  height: 100%;
  overflow: hidden;
}

.container {
  height: 1000vh;
}

.n-config-provider {
  width: 100%;
  height: 100%;
  overflow: hidden;

  &>.n-element>.n-spin-container {
    width: 100vw;
    height: 100vh;
    overflow: hidden;

    .n-spin-content {
      width: 100vw;
      height: 100vh;
      overflow: hidden;
    }
  }
}

.side-bar {
  // 头像占位
  padding-top: 90px;
  max-width: 60px !important;
  height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: start;
  background-color: rgb(47, 47, 47);

  .n-menu {
    height: 100%;
    --n-item-icon-color: #97969B !important;
    --n-item-text-color: #97969B !important;
    --n-item-icon-color-active: #FFFFFF !important;
    --n-item-text-color-active: #FFFFFF !important;
    --n-item-icon-color-active-hover: #FFFFFF !important;
    --n-item-text-color-active-hover: #FFFFFF !important;
    --n-border-radius: 0 !important;

    .n-menu-item {
      height: 59px;

      .n-menu-item-content {
        padding: 0 !important;
        width: 60px !important;
        height: 59px;
        display: flex;
        flex-direction: column;
        justify-content: center;
        margin: 10px 0;

        .n-menu-item-content__icon {
          margin-right: 0 !important;
        }

        .n-menu-item-content-header {
          font-size: 12px;
          line-height: 14px;
          margin-top: 5px;
        }

        &.n-menu-item-content--selected {
          background-color: #151419 !important;

          &::before {
            display: none;
          }

          .n-menu-item-content__icon {
            font-size: 20px !important;
          }
        }
      }

      ::before {
        background-color: transparent;
      }
    }
  }
}

.page {
  width: 100%;
  height: 100%;
  background-color: #151419;
}

.n-dynamic-tags button {
  --n-border-hover: 1px solid #4098fc !important;
  --n-border-focus: 1px solid #4098fc !important;
}

.n-base-selection {
  --n-border-hover: none !important;
  --n-box-shadow-active: none !important;
}

.n-input textarea,
.n-input input,
.n-base-selection input {
  caret-color: #4098fc !important;
}

.n-upload {
  --n-dragger-border-hover: 1px dashed #4098fc !important;
}

.n-dynamic-tags button {
  --n-text-color-hover: #4098fc !important;
}

.n-card-header {
  --n-padding-top: 12px !important;
  --n-padding-bottom: 13px !important;
  --n-padding-left: 15px !important;

  .n-card-header__extra {
    cursor: pointer;
  }
}

.n-menu-item-content {
  padding: 5px 0;
}

.n-menu-item-content::before {
  left: 0 !important;
  right: 0 !important;
}

// :deep(.n-modal) {
//   padding: 30px 70px !important;
//   box-sizing: border-box;
// }
.userCenter {
  width: 358px;
  height: 295px;
  background: #18171D;
  border-radius: 10px;
  border: 1px solid #5A5A62;

  .n-card-header {
    padding: 20px 30px;
  }

  .n-card__content {
    padding: 0 30px 20px !important;

    div {
      margin-bottom: 15px;
    }
  }

  .n-card__footer {
    display: flex;
    justify-content: space-evenly;
  }
}

// .n-card__footer: {
//   display: flex;
//   justify-content: space-between;
// }

:deep(.n-card) {
  .n-card__footer {
    .n-button--default-type {
      margin-right: 20px !important;
    }
  }
}

.n-card>.n-card__content {
  padding: 0px 70px 30px;
}

.changPwd {
  height: 32px;
  border-radius: 25px;
  border: 1px solid #8F83CB;
  font-size: 12px !important;
  text-align: center;

}

.logOut {
  height: 32px;
  border-radius: 25px;
  border: 1px solid #FF4646;
  font-size: 12px !important;
  text-align: center !important;
}

.changePwd {
  height: 302px;
  width: 478px !important;
  // height: 270px;
  background: #18171D;
  border-radius: 10px;
  border: 1px solid #5A5A62;

  .n-card-header {
    padding: 20px 30px
  }

  .n-card__content {
    font-size: 14px;
    padding-bottom: 0;
    padding: 0 30px 0;

    :deep(.n-input) {
      width: 350px !important;
      height: 36px !important;
      background: #25242B;
      border-radius: 4px;
      border: 1px solid #5A5A62;
    }
  }

  .n-card__footer {
    display: flex;
    flex-direction: row;
    justify-content: end;

    .n-button {
      width: 80px;
      height: 32px;
      background: rgba(190, 164, 255, 0.4);
      border-radius: 25px;
      border: 1px solid #8F83CB;
    }

    .nochange {
      background: #25242B;
      border: 1px solid #5A5A62;
    }
  }
}
</style>
